#ifndef HTTP_REQUEST_H
#define HTTP_REQUEST_H

#include <unordered_map>
#include <unordered_set>
#include <string>
#include <regex>
#include <errno.h>
#include <mysql/mysql.h>

#include "../Buffer/buffer.h"
#include "../Log/log.h"
#include "../Pool/sqlconnpool.h"

class HttpRequest
{
public:
    enum PARSE_STATE {  // 表示HTTP请求解析的不同阶段，从请求行到请求体，直到请求解析完成
        REQUEST_LINE,   // 正在解析请求首行
        HEADERS,        // 请求头
        BODY,           // 请求体
        FINISH,         // 结束
    };

    enum HTTP_CODE {    // 列举了处理Http请求时可能出现的几种状态，如GET请求、错误请求、资源未找到等
        NO_REQUEST = 0,
        GET_REQUEST,
        BAD_REQUEST,
        NO_RESOURCE,
        FORBIDDENT_REQUEST,
        FILE_REQUEST,
        INTERNAL_ERROR,
        CLOSED_CONNECTION,
    };

    HttpRequest() {Init();}
    ~HttpRequest() = default;

    void Init();                // 重置所有成员变量至初识状态，准备开始新的Http请求解析
    bool parse(Buffer& buff);   // 核心解析方法，接受一个buffer对象作为参数，从中读取Http请求流并逐步解析各个部分

    // 请求属性获取方法
    std::string path() const;   // 用于获取Http请求的路径
    std::string& path();        // 用于获取Http请求的路径
    std::string method() const; // 用户获取Http请求的方法
    std::string version() const;// 用于获取Http版本号

    // POST数据获取
    std::string GetPost(const std::string& key) const;  // 获取post请求中的表单数据
    std::string GetPost(const char* key) const;

    // 连接管理
    bool IsKeepAlive() const;   // 检查Http头部的connection字段，确定是否为长连接请求

private:
    bool ParseRequestLine_(const std::string& line);    // 解析Http请求的第一行，即请求行（Method, Path, Version)
    void ParseHeader_(const std::string& line);         // 逐行解析Http请求头部，将键值对存储在header_映射中
    void ParseBody_(const std::string& line);           // 解析请求体

    void ParsePath_();      // 处理请求路径，比如将默认资源路径自动加上.html扩展名
    void ParsePost_();      // 处理post请求数据，例如对URL编码的数据进行解码并存入post_映射
    void ParseFromUrlencoded_();    // 专门用于解析post请求中采用URL编码方式的表单数据

    static bool UserVerify(const std::string& name, const std::string&
                            pwd, bool isLogin); // 用于验证用户的登录凭据

    PARSE_STATE state_;     // 记录当前解析状态
    std::string method_, path_, version_, body_;            // 分别存储请求方法、路径、Http版本和请求体内容 
    std::unordered_map<std::string, std::string> header_;   // 使用unordered_map存储请求头部的所有键值对
    std::unordered_map<std::string, std::string> post_;     // 使用unordered_map存储post请求的表单数据

    static const std::unordered_set<std::string> DEFAULT_HTML;          // 预定义的一组默认HTML资源路径集合
    static const std::unordered_map<std::string, int> DEFAULT_HTML_TAG; // HTML资源到标签的映射
    static int ConverHex(char ch);  // 转换成16进制             
};

#endif